# 导入必要的库

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from scipy import stats

# 设置中文显示
plt.rcParams["font.family"] = ["SimHei", "WenQuanYi Micro Hei", "Heiti TC"]
plt.rcParams["axes.unicode_minus"] = False  # 解决负号显示问题

# 1. 加载数据集（直接下载 tab 分隔的文本文件）
import requests
from io import StringIO

# 数据集的直接下载链接（从原网页提取的真实数据文件）
data_url = "https://www4.stat.ncsu.edu/~boos/var.select/diabetes.data"
# 发送请求获取数据
response = requests.get(data_url)
response.encoding = "utf-8"

# 将文本数据转换成 DataFrame
data = pd.read_csv(
    StringIO(response.text),  # 把文本转换成 pandas 可读取的格式
    sep="\t",  # 数据是 tab 分隔的
    header=None,  # 数据文件没有表头
    names=["AGE", "SEX", "BMI", "BP", "S1", "S2", "S3", "S4", "S5", "S6", "Y"]  # 手动添加表头（对应原数据的11个变量）
)

# 查看数据基本信息
print("数据集基本信息：")
print(f"形状：{data.shape}")
print("\n前5行数据：")
print(data.head())

# 2. 计算所有值的平均值和方差
# 计算数值型列的平均值和方差
numeric_cols = data.select_dtypes(include=np.number).columns
mean_values = data[numeric_cols].mean()
var_values = data[numeric_cols].var()

# 整理成DataFrame显示
stats_df = pd.DataFrame({
    "平均值": mean_values,
    "方差": var_values
})
print("\n各变量的平均值和方差：")
print(stats_df)

# 3. 根据性别绘制BMI、BP和Y的箱线图
plt.figure(figsize=(15, 5))

# BMI箱线图
plt.subplot(1, 3, 1)
sns.boxplot(x="SEX", y="BMI", data=data)
plt.title("不同性别BMI分布")
plt.xlabel("性别 (1=男性, 2=女性)")

# BP箱线图
plt.subplot(1, 3, 2)
sns.boxplot(x="SEX", y="BP", data=data)
plt.title("不同性别血压(BP)分布")
plt.xlabel("性别 (1=男性, 2=女性)")

# Y(疾病进展)箱线图
plt.subplot(1, 3, 3)
sns.boxplot(x="SEX", y="Y", data=data)
plt.title("不同性别疾病进展(Y)分布")
plt.xlabel("性别 (1=男性, 2=女性)")

plt.tight_layout()
plt.show()

# 4. 分析年龄、性别、BMI和Y变量的分布
plt.figure(figsize=(16, 12))

# 年龄分布
plt.subplot(2, 2, 1)
sns.histplot(data["AGE"], kde=True, bins=15)
plt.title("年龄分布")
plt.xlabel("年龄")

# 性别分布
plt.subplot(2, 2, 2)
sex_counts = data["SEX"].value_counts().rename({1: "男性", 2: "女性"})
sns.barplot(x=sex_counts.index, y=sex_counts.values)
plt.title("性别分布")
plt.xlabel("性别")
plt.ylabel("人数")

# BMI分布
plt.subplot(2, 2, 3)
sns.histplot(data["BMI"], kde=True, bins=15)
plt.title("BMI分布")
plt.xlabel("BMI指数")

# Y(疾病进展)分布
plt.subplot(2, 2, 4)
sns.histplot(data["Y"], kde=True, bins=15)
plt.title("疾病进展程度(Y)分布")
plt.xlabel("疾病进展值")

plt.tight_layout()
plt.show()

# 5. 测试不同变量与疾病进展(Y)之间的相关性
# 计算相关系数
corr_with_y = data[numeric_cols].corr()["Y"].sort_values(ascending=False)
print("\n各变量与疾病进展(Y)的相关系数：")
print(corr_with_y)

# 可视化相关性（热图）
plt.figure(figsize=(10, 8))
corr_matrix = data[numeric_cols].corr()
sns.heatmap(corr_matrix, annot=True, cmap="coolwarm", vmin=-1, vmax=1)
plt.title("变量间相关性热图")
plt.show()

# 6. 检验男性和女性糖尿病进展程度不同的假设
# 分离男性和女性的Y值
male_y = data[data["SEX"] == 1]["Y"]
female_y = data[data["SEX"] == 2]["Y"]

# 打印基本统计量
print("\n男性糖尿病进展统计：")
print(f"样本量：{len(male_y)}，平均值：{male_y.mean():.2f}，标准差：{male_y.std():.2f}")
print("\n女性糖尿病进展统计：")
print(f"样本量：{len(female_y)}，平均值：{female_y.mean():.2f}，标准差：{female_y.std():.2f}")

# 进行独立样本t检验（假设方差齐性）
t_stat, p_value = stats.ttest_ind(male_y, female_y, equal_var=True)
print(f"\nt检验结果：t统计量={t_stat:.4f}，p值={p_value:.4f}")

# 解释结果
alpha = 0.05
if p_value < alpha:
    print(f"由于p值({p_value:.4f}) < {alpha}，拒绝原假设，认为男性和女性的糖尿病进展程度存在显著差异")
else:
    print(f"由于p值({p_value:.4f}) >= {alpha}，不拒绝原假设，没有足够证据表明男性和女性的糖尿病进展程度存在显著差异")

# 可视化男女Y值分布差异
plt.figure(figsize=(8, 6))
sns.histplot(male_y, kde=True, label="男性", alpha=0.5)
sns.histplot(female_y, kde=True, label="女性", alpha=0.5)
plt.title("男性和女性糖尿病进展程度分布对比")
plt.xlabel("疾病进展值(Y)")
plt.legend()
plt.show()